package router

import (
	"github.com/gin-gonic/gin"
	grpcmiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
	grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/resolver"
	"log"
	"net"
	"vben-admin/api/middleware/zap"
	"vben-admin/config"
	buttonServiceV1 "vben-admin/pkg/service/button.service.v1"
	interfaceServiceV1 "vben-admin/pkg/service/interface.service.v1"
	menuServiceV1 "vben-admin/pkg/service/menu.service.v1"
	roleServiceV1 "vben-admin/pkg/service/role.service.v1"
	systemServiceV1 "vben-admin/pkg/service/system.service.v1"
	userServiceV1 "vben-admin/pkg/service/user.service.v1"
	"vben-admin/pkg/svc"
	"vben-common/discovery"
	"vben-common/logs"
	grpcButtonService "vben-grpc-common/vben-admin/types/button.service.v1"
	grpcInterfaceService "vben-grpc-common/vben-admin/types/interface.service.v1"
	grpcMenuService "vben-grpc-common/vben-admin/types/menu.service.v1"
	grpcRoleService "vben-grpc-common/vben-admin/types/role.service.v1"
	grpcSystemService "vben-grpc-common/vben-admin/types/system.service.v1"
	grpcUserService "vben-grpc-common/vben-admin/types/user.service.v1"
)

// Router 路由接口
type Router interface {
	Route(r *gin.Engine)
}

type RegisterRouter struct {
}

func New() *RegisterRouter {
	return &RegisterRouter{}
}

func (*RegisterRouter) Route(ro Router, r *gin.Engine) {
	ro.Route(r)
}

var routers []Router

func InitRouter(r *gin.Engine) {
	for _, ro := range routers {
		ro.Route(r)
	}
}

func Register(ro ...Router) {
	routers = append(routers, ro...)
}

type gRPCConfig struct {
	Addr         string
	RegisterFunc func(server *grpc.Server)
}

func RegisterGrpc(svcCtx *svc.ServiceContext) *grpc.Server {
	c := gRPCConfig{
		Addr: config.C.GC.Addr,
		RegisterFunc: func(server *grpc.Server) {
			// GRPC服务注册...
			grpcSystemService.RegisterSystemServiceServer(server, systemServiceV1.NewSystemService(svcCtx))
			grpcMenuService.RegisterMenuServiceServer(server, menuServiceV1.NewMenuService(svcCtx))
			grpcRoleService.RegisterRoleServiceServer(server, roleServiceV1.NewRoleService(svcCtx))
			grpcUserService.RegisterUserServiceServer(server, userServiceV1.NewUserService(svcCtx))
			grpcInterfaceService.RegisterInterfaceServiceServer(server, interfaceServiceV1.NewInterfaceService(svcCtx))
			grpcButtonService.RegisterButtonServiceServer(server, buttonServiceV1.NewButtonService(svcCtx))
		},
	}
	var opts []grpc.ServerOption
	opts = append(opts, grpc.UnaryInterceptor(grpcmiddleware.ChainUnaryServer(
		grpczap.UnaryServerInterceptor(zap.ConsoleInterceptorZap()),
		// grpc_auth.UnaryServerInterceptor(auth.AuthInterceptor),
		// grpc_recovery.UnaryServerInterceptor(recovery.RecoveryInterceptor()),
	)))
	s := grpc.NewServer(opts...)
	c.RegisterFunc(s)
	lis, err := net.Listen("tcp", c.Addr)
	if err != nil {
		log.Println("cannot listen grpc")
	}
	go func() {
		err = s.Serve(lis)
		if err != nil {
			log.Println("server started error ", err)
			return
		}
	}()
	return s
}

func RegisterEtcdServer() {
	etcdRegister := discovery.NewResolver(config.C.EtcdConfig.Addrs, logs.LG)
	resolver.Register(etcdRegister)
	info := discovery.Server{
		Name:    config.C.GC.Name,
		Addr:    config.C.GC.Addr,
		Version: config.C.GC.Version,
		Weight:  config.C.GC.Weight,
	}
	r := discovery.NewRegister(config.C.EtcdConfig.Addrs, logs.LG)
	_, err := r.Register(info, 60)
	if err != nil {
		log.Fatalln(err)
	}
}
